import 'package:json_annotation/json_annotation.dart';

import 'text_config.dart';

part 'graphic.g.dart';

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class Style {
  var image;
  var x;
  var y;
  var width;
  var height;
  var fill; //color
  var stroke;
  var lineWidth;
  var shadowBlur;
  var shadowOffsetX;
  var shadowOffsetY;
  var shadowColor;

  Style(
      {this.image,
      this.x,
      this.y,
      this.width,
      this.height,
      this.fill,
      this.stroke,
      this.lineWidth,
      this.shadowBlur,
      this.shadowOffsetX,
      this.shadowOffsetY,
      this.shadowColor});

  factory Style.fromJson(Map<String, dynamic> json) => _$StyleFromJson(json);

  Map<String, dynamic> toJson() => _$StyleToJson(this);
}

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class Graphic {
  var id;
  List<Element>? elements;

  Graphic({this.id, this.elements});

  factory Graphic.fromJson(Map<String, dynamic> json) =>
      _$GraphicFromJson(json);

  Map<String, dynamic> toJson() => _$GraphicToJson(this);
}

//group
@JsonSerializable(includeIfNull: false, explicitToJson: true)
class Element {
  Element();

  factory Element.fromJson(Map<String, dynamic> json) =>
      _$ElementFromJson(json);

  Map<String, dynamic> toJson() => _$ElementToJson(this);
}

//text image
@JsonSerializable(includeIfNull: false, explicitToJson: true)
class ImageTextElement extends Element {
  var type;
  var id;
  var $action;
  var x;
  var y;

  var rotation;
  var scaleX;
  var scaleY;
  var originX;
  var originY;

  var left;
  var top;
  var right;
  var bottom;
  var bounding;

  var z;
  var zlvel;
  var info;
  var silent;
  var invisible;

  var ignore;
  var textContent;
  TextConfig? textConfig;
  var cursor;
  var draggable;

  var progressive;
  var width;
  var height;
  var diffChildrenByName;
  var children;

  var onclick;
  var onmouseover; //function
  var onmouseout;
  var onmousemove;
  var onmousewheel;

  var onmousedown;
  var onmouseup;
  var ondrag;
  var dragstart;
  var dragend;

  var dragenter;
  var dragover;
  var ondrop;
  Style? style;
  var focus;
  var blurScope;

  ImageTextElement(
      {this.type,
      this.id,
      this.$action,
      this.x,
      this.y,
      this.rotation,
      this.scaleX,
      this.scaleY,
      this.originX,
      this.originY,
      this.left,
      this.top,
      this.right,
      this.bottom,
      this.bounding,
      this.z,
      this.zlvel,
      this.info,
      this.silent,
      this.invisible,
      this.ignore,
      this.textContent,
      this.textConfig,
      this.cursor,
      this.draggable,
      this.progressive,
      this.width,
      this.height,
      this.diffChildrenByName,
      this.children,
      this.onclick,
      this.onmouseover,
      this.onmouseout,
      this.onmousemove,
      this.onmousewheel,
      this.onmousedown,
      this.onmouseup,
      this.ondrag,
      this.dragstart,
      this.dragend,
      this.dragenter,
      this.dragover,
      this.ondrop,
      this.style,
      this.focus,
      this.blurScope});

  factory ImageTextElement.fromJson(Map<String, dynamic> json) =>
      _$ImageTextElementFromJson(json);

  Map<String, dynamic> toJson() => _$ImageTextElementToJson(this);
}

//rect  circle ring sector arc polygon polyline line bezierCurve
@JsonSerializable(includeIfNull: false, explicitToJson: true)
class ShapeElement extends Element {
  var type;
  var id;
  var $action;
  var x;
  var y;

  var rotation;
  var scaleX;
  var scaleY;
  var originX;
  var originY;

  var left;
  var top;
  var right;
  var bottom;
  var bounding;

  var z;
  var zlvel;
  var info;
  var silent;
  var invisible;

  var ignore;
  var textContent;
  TextConfig? textConfig;
  var cursor;
  var draggable;

  var progressive;
  var width;
  var height;
  var diffChildrenByName;
  var children;

  var onclick;
  var onmouseover; //function
  var onmouseout;
  var onmousemove;
  var onmousewheel;

  var onmousedown;
  var onmouseup;
  var ondrag;
  var dragstart;
  var dragend;

  var dragenter;
  var dragover;
  var ondrop;
  Style? style;
  var focus;
  var blurScope;
  Shape? shape;

  ShapeElement(
      {this.type,
      this.id,
      this.$action,
      this.x,
      this.y,
      this.rotation,
      this.scaleX,
      this.scaleY,
      this.originX,
      this.originY,
      this.left,
      this.top,
      this.right,
      this.bottom,
      this.bounding,
      this.z,
      this.zlvel,
      this.info,
      this.silent,
      this.invisible,
      this.ignore,
      this.textContent,
      this.textConfig,
      this.cursor,
      this.draggable,
      this.progressive,
      this.width,
      this.height,
      this.diffChildrenByName,
      this.children,
      this.onclick,
      this.onmouseover,
      this.onmouseout,
      this.onmousemove,
      this.onmousewheel,
      this.onmousedown,
      this.onmouseup,
      this.ondrag,
      this.dragstart,
      this.dragend,
      this.dragenter,
      this.dragover,
      this.ondrop,
      this.style,
      this.focus,
      this.blurScope,
      this.shape});

  factory ShapeElement.fromJson(Map<String, dynamic> json) =>
      _$ShapeElementFromJson(json);

  Map<String, dynamic> toJson() => _$ShapeElementToJson(this);
}

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class RectShape extends Shape {
  var x;
  var y;
  var width;
  var height;
  var r;

  RectShape({this.x, this.y, this.width, this.height, this.r});

  factory RectShape.fromJson(Map<String, dynamic> json) =>
      _$RectShapeFromJson(json);

  Map<String, dynamic> toJson() => _$RectShapeToJson(this);
}

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class CircleShape extends Shape {
  var cx;
  var cy;
  var r;

  CircleShape({this.cx, this.cy, this.r});

  factory CircleShape.fromJson(Map<String, dynamic> json) =>
      _$CircleShapeFromJson(json);

  Map<String, dynamic> toJson() => _$CircleShapeToJson(this);
}

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class RingShape extends Shape {
  var cx;
  var cy;
  var r;
  var r0;

  RingShape({this.cx, this.cy, this.r, this.r0});

  factory RingShape.fromJson(Map<String, dynamic> json) =>
      _$RingShapeFromJson(json);

  Map<String, dynamic> toJson() => _$RingShapeToJson(this);
}

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class SectorArcShape extends Shape {
  var cx;
  var cy;
  var r;
  var r0;
  var startAngle;
  var endAngle;
  var clockwise;

  SectorArcShape(
      {this.cx,
      this.cy,
      this.r,
      this.r0,
      this.startAngle,
      this.endAngle,
      this.clockwise});

  factory SectorArcShape.fromJson(Map<String, dynamic> json) =>
      _$SectorArcShapeFromJson(json);

  Map<String, dynamic> toJson() => _$SectorArcShapeToJson(this);
}

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class PolyShape extends Shape {
  var points;
  var smooth;
  var smoothConstraint;

  PolyShape({this.points, this.smooth, this.smoothConstraint});

  factory PolyShape.fromJson(Map<String, dynamic> json) =>
      _$PolyShapeFromJson(json);

  Map<String, dynamic> toJson() => _$PolyShapeToJson(this);
}

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class LineShape extends Shape {
  var x1;
  var x2;
  var y1;
  var y2;
  var percent;

  LineShape({this.x1, this.x2, this.y1, this.y2, this.percent});

  factory LineShape.fromJson(Map<String, dynamic> json) =>
      _$LineShapeFromJson(json);

  Map<String, dynamic> toJson() => _$LineShapeToJson(this);
}

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class BezierCurveShape extends Shape {
  var x1;
  var x2;
  var y1;
  var y2;
  var cpx1;
  var cpy1;
  var cpx2;
  var cpy2;
  var percent;

  BezierCurveShape(
      {this.x1,
      this.x2,
      this.y1,
      this.y2,
      this.cpx1,
      this.cpy1,
      this.cpx2,
      this.cpy2,
      this.percent});

  factory BezierCurveShape.fromJson(Map<String, dynamic> json) =>
      _$BezierCurveShapeFromJson(json);

  Map<String, dynamic> toJson() => _$BezierCurveShapeToJson(this);
}

@JsonSerializable(includeIfNull: false, explicitToJson: true)
class Shape {
  Shape();

  factory Shape.fromJson(Map<String, dynamic> json) => _$ShapeFromJson(json);

  Map<String, dynamic> toJson() => _$ShapeToJson(this);
}
